import { SyncOutlined } from "@ant-design/icons"
import { Button, DatePicker, Flex, Select, Switch } from "antd"
import dayjs from "dayjs"
import moment from "moment"
/**
 * 数据记录工具栏
 * 用于选择班次和场次，以及数据记录动作
 */

import React, { useEffect, useState } from "react"

import { sendToBackground } from "@plasmohq/messaging"
import { usePort } from "@plasmohq/messaging/hook"
import { useStorage } from "@plasmohq/storage/hook"

import { transformDataKey } from "~utils/dataScreenParser"
import {
  _callApi,
  getPlatform,
  getUserInfo,
  getUserShopList
} from "~utils/tools"

/**
 * 数据记录工具栏组件
 * @constructor
 */
// 组件参数定义
type DataRecordToolbarProps = {
  // 设置表格数据方法
  setTableData: (data: any[]) => void
  // 网络拦截数据
  hijackData?: any
}
const DataRecordToolbar: React.FC<DataRecordToolbarProps> = ({
  setTableData,
  hijackData
}) => {
  // 选择的店铺id
  const [prefixId, setPrefixId] = useState<undefined | number>(undefined)
  // 店铺列表options
  const [prefixList, setPrefixList] = useState([])
  // 班次列表options
  const [classList, setClassList] = useState([])
  // 场次列表options
  const [playList, setPlayList] = useState([])
  // 选择的班次id
  const [classId, setClassId] = useState()
  // 选择的场次id
  const [playId, setPlayId] = useState()
  // 当前日期day
  const [day, setDay] = useState(moment().format("YYYY-MM-DD"))
  // 记录按钮禁用状态
  const [recordBtnDisabled, setRecordBtnDisabled] = useState(true)
  // 记录按钮加载状态
  const [recordBtnLoading, setRecordBtnLoading] = useState(false)
  // 刷新按钮加载状态
  const [refreshBtnLoading, setRefreshBtnLoading] = useState(false)
  // 删除数据触发storage
  const [deleteDataId, setDeleteDataId] = useStorage("deleteRecordId", 0)
  // 错误信息txt
  const [errTxt, setErrTxt] = useState("")
  // 成功信息txt
  const [successTxt, setSuccessTxt] = useState("")
  // 数据记录弹窗显示状态通信port
  const visiblePort = usePort("recordModalVisible")
  // // 是否需要自定义开播时间
  // const [isCustomLiveTime, setIsCustomLiveTime] = useState(false)
  // // 开播时间
  // const [liveTime, setLiveTime] = useState("")
  // 登录状态
  const [loginStatus] = useStorage("isLogin")
  // 下播状态
  const [isEnd, setIsEnd] = useState(false)
  // 监控登录状态
  useEffect(() => {
    if (loginStatus) {
      // 重新获取店铺列表
      handleGetPrefixList().then()
    }
  }, [loginStatus])
  // 监控店铺id变化，变化后，请求班次列表数据和表格数据
  useEffect(() => {
    handleGetClassList().then()
    handleGetRecordList().then()
  }, [prefixId])
  // 监控日期更改，更改后，请求班次列表数据和表格数据
  useEffect(() => {
    handleGetClassList().then()
    handleGetRecordList().then()
  }, [day])
  // 监控班次id、场次id和开播时间变化，设置记录按钮禁用状态
  useEffect(() => {
    if (classId && playId) {
      setRecordBtnDisabled(false)
    } else {
      setRecordBtnDisabled(true)
    }
  }, [classId, playId])
  // 监控班次id变化，变化后，请求场次列表数据
  useEffect(() => {
    if (!classId) return
    handleGetPlayList().then()
  }, [classId])
  // 加载完成后，请求班次列表数据和表格数据,设置店铺列表
  useEffect(() => {
    // 获取店铺列表
    handleGetPrefixList().then()
  }, [])
  // 删除触发
  useEffect(() => {
    if (deleteDataId === 0) return
    // 删除数据
    _callApi("deletePlayLiveData", deleteDataId).then((res) => {
      if (res.err) {
        console.log(res.err)
      } else {
        // 清空删除记录id
        setDeleteDataId(0).then()
        // 请求表格数据
        handleGetRecordList().then()
      }
    })
  }, [deleteDataId])
  // 处理获取店铺列表数据
  const handleGetPrefixList = async () => {
    // 获取店铺列表
    const res = await getUserShopList()
    // 将res改造为{value,label}格式
    const list = []
    res.forEach((item: any) => {
      list.push({
        value: item.id,
        label: item.name
      })
    })
    setPrefixList(list)
    // 如果res不为空，设置默认店铺id
    if (res.length > 0) {
      setPrefixId(res[0].id)
    } else {
      // 如果res为空，设置默认店铺id为空
      setPrefixId(undefined)
    }
  }
  // 获取shadowRoot的对话框元素
  const getShadowRootModalElement = () => {
    const outWrapperElement = document.querySelector("plasmo-csui")
    if (outWrapperElement.shadowRoot) {
      return outWrapperElement.shadowRoot.querySelector(".ant-modal-wrap")
    }
    return undefined
  }
  // 监控对话框关闭状态
  // 使用mutationObserver监控对象
  const handleMutationModalVisible = async () => {
    return await new Promise((resolve) => {
      // 超时检查定时器
      let observerTimer = null
      // shadowRoot的对话框元素
      const shadowRootElement = getShadowRootModalElement()
      // body内的对话框元素
      const modalElement = document.querySelector(".ant-modal-wrap") // 根据实际的弹窗选择器修改

      // 目标元素
      const targetElement = shadowRootElement || modalElement

      if (!targetElement) {
        // 找不到目标元素，采用等待超时的方式
        // 发送关闭信号
        visiblePort.send({
          visible: false
        })
        setTimeout(() => {
          resolve(true)
        }, 1000)
      } else {
        // 创建一个MutationObserver实例
        const observer = new MutationObserver((mutationsList, observer) => {
          for (let mutation of mutationsList) {
            if (
              mutation.type === "attributes" &&
              mutation.attributeName === "style"
            ) {
              if (targetElement["style"].display === "none") {
                observer.disconnect() // 停止观察
                clearTimeout(observerTimer)
                resolve(true) // 弹窗关闭，解析Promise
              }
            }
          }
        })

        // 配置观察选项
        const config = { attributes: true, childList: false, subtree: false }

        // 开始观察目标节点
        observer.observe(targetElement, config)
        // 发送关闭信号
        visiblePort.send({
          visible: false
        })

        // 设置一个超时，以防观察不到关闭事件
        observerTimer = setTimeout(() => {
          observer.disconnect() // 停止观察
          resolve(false)
        }, 10000) // 设置超时时间为10秒
      }
    })
  }
  // 处理点击数据记录动作
  const handleRecord = async () => {
    if (recordBtnLoading) {
      return
    }
    // 设置按钮加载状态
    setRecordBtnLoading(true)
    try {
      const platform = getPlatform(window.location.href)
      // 获取hijackData
      const hijackDataCopy = { ...hijackData }
      // 如果live_end=false，为未下播，删除live_end_time
      if (!hijackDataCopy["live_end"]) {
        delete hijackDataCopy["live_end_time"]
      }
      // 获取系统数据
      const sysInfo = await sendToBackground({
        name: "sysInfoService",
        body: {}
      })
      // 远程解析html获取数据
      // 构建api请求参数
      const params = {
        htmlContent: "",
        image_hash: "",
        // hijack_data: JSON.stringify(hijackData),
        platform: platform,
        classs: Number(classId),
        play: Number(playId),
        prefix: prefixId,
        creator: await getUserInfo("id"),
        live_record_time: moment().format("YYYY-MM-DD HH:mm:ss"),
        desc: sysInfo.infoTxt,
        ...hijackDataCopy,
        is_end: isEnd
      }
      // 获取页面body
      params["htmlContent"] = document.body.innerHTML
      // 获取截图hash
      // params["image_hash"] = await uploadScreenshot()

      // --截图处理
      // 关闭数据记录弹窗
      // 等待showRecordModal关闭
      await handleMutationModalVisible()

      // 发送截图请求
      const { image } = await sendToBackground({
        name: "captureScreenService",
        body: {
          toSave: false
        }
      })
      // 上传到七牛云，并返回图片Hash
      const { hash } = await sendToBackground({
        name: "qiniuService",
        body: {
          imgBase64: image
        }
      })
      params["image_hash"] = hash

      // 检查params是否含有extra_data，需要格式化为后端识别的json对象
      if (params["extra_data"]) {
        params["extra_data"] = JSON.stringify(params["extra_data"])
      }

      // 发送到后端 api dataParser
      const res = await _callApi("dataParser", params)
      // 如果err存在，打印错误信息
      if (res.err) {
        console.log(res.err)
        // 显示错误
        setErrTxt("网络请求错误!")
        // 10秒后清空错误信息
        setTimeout(() => {
          setErrTxt("")
        }, 10000)
      } else {
        // 检查res.data是否含有error键
        if (res.data.error) {
          // 显示错误
          setErrTxt(res.data.error)
          // 10秒后清空错误信息
          setTimeout(() => {
            setErrTxt("")
          }, 10000)
        } else {
          // 显示成功
          setSuccessTxt("数据已记录，在数据记录列表查看第一条")
          // 5秒后清空成功信息
          setTimeout(() => {
            setSuccessTxt("")
          }, 5000)
          // 刷新列表
          handleGetRecordList().then()
        }
      }
    } catch (e) {
      console.log(e)
    }
    // 显示数据记录弹窗
    visiblePort.send({
      visible: true
    })
    // 设置按钮加载状态
    setRecordBtnLoading(false)
    // 下播推送状态设置False
    setIsEnd(false)
  }
  // 处理请求班次列表数据
  const handleGetClassList = async () => {
    // 如果prefixId不存在，返回
    if (!prefixId) return
    // 清空班次id
    setClassId(undefined)
    // 清空场次id
    setPlayId(undefined)
    // 清空场次列表
    setPlayList([])
    // 后端请求
    const res = await _callApi("getClass", {
      prefix_id: prefixId,
      day: day
    })
    if (res.err) {
      console.log(res.err)
    } else {
      setClassList(res.data || [])
    }
  }
  // 处理请求场次列表数据
  const handleGetPlayList = async () => {
    setPlayId(undefined)
    // 后端请求
    const res = await _callApi("getPlays", { class_id: classId })
    if (res.err) {
      console.log(res.err)
    } else {
      setPlayList(res.data || [])
    }
  }
  // 处理请求直播记录数据列表
  const handleGetRecordList = async () => {
    if (!prefixId) return
    // 设置按钮加载状态
    setRefreshBtnLoading(true)
    // 请求参数
    const params = {
      select_prefix_ids: [prefixId].join(","),
      day: day
    }
    // 后端请求
    const res = await _callApi("getPlayLiveDataList", params)
    if (res.err) {
      console.log(res.err)
    } else {
      // 装换数据key
      const newData = []
      res.data.forEach((item: any) => {
        newData.push(transformDataKey(item, "front"))
      })
      // 设置表格数据
      setTableData(newData)
    }
    // 设置按钮加载状态
    setRefreshBtnLoading(false)
  }
  return (
    <div className={"data-select-tools"}>
      <Flex gap="middle" justify={"space-between"}>
        <div>
          <div className={"tools-item"} style={{ marginBottom: 10 }}>
            <label>店铺:</label>
            <Select
              value={prefixId}
              size={"small"}
              style={{ width: 150 }}
              getPopupContainer={(trigger) => {
                return trigger.parentNode
              }}
              showSearch
              filterOption={(input, option) => {
                return (
                  option?.label?.toLowerCase().indexOf(input.toLowerCase()) >= 0
                )
              }}
              placeholder={"请选择店铺"}
              options={prefixList}
              onChange={(value) => setPrefixId(value)}></Select>
            <label style={{ paddingLeft: "10px" }}>直播班次:</label>
            <Select
              value={classId}
              getPopupContainer={(trigger) => {
                return trigger.parentNode
              }}
              size={"small"}
              style={{ width: 360 }}
              placeholder={"请选择主播直播班次"}
              onChange={(value) => setClassId(value)}
              options={classList}></Select>
            <Button
              type={"text"}
              size={"small"}
              icon={<SyncOutlined />}
              style={{ color: "green" }}
              onClick={handleGetClassList}>
              刷新
            </Button>
          </div>
        </div>

        <div>
          <DatePicker
            defaultValue={dayjs(day, "YYYY-MM-DD")}
            size={"small"}
            allowClear={false}
            getPopupContainer={(trigger) => {
              return trigger.parentNode as HTMLElement
            }}
            onChange={(date) => {
              if (date) {
                setDay(date.format("YYYY-MM-DD"))
              }
            }}
          />
        </div>
      </Flex>
      <Flex gap="middle" justify={"space-between"}>
        <Flex gap="middle" justify={"flex-start"}>
          <div className={"tools-item"}>
            <label>货主场次:</label>
            <Select
              value={playId}
              getPopupContainer={(trigger) => {
                return trigger.parentNode
              }}
              size={"small"}
              style={{ width: 551 }}
              placeholder={"请选择货主场次"}
              onChange={(value) => setPlayId(value)}
              options={playList}></Select>
            <Button
              type={"text"}
              size={"small"}
              icon={<SyncOutlined />}
              style={{ color: "green" }}
              onClick={handleGetPlayList}>
              刷新
            </Button>
          </div>
        </Flex>
        <div>
          <Switch
            checkedChildren="下播推送"
            unCheckedChildren="直播中"
            checked={isEnd}
            style={{ marginRight: "10px" }}
            onChange={(checked) => {
              setIsEnd(checked)
            }}
          />
          <Button
            disabled={recordBtnDisabled}
            type={"primary"}
            size={"small"}
            loading={recordBtnLoading}
            onClick={handleRecord}>
            数据记录
          </Button>
          <Button
            type={"text"}
            size={"small"}
            loading={refreshBtnLoading}
            icon={<SyncOutlined />}
            style={{ color: "green" }}
            onClick={handleGetRecordList}>
            刷新表格
          </Button>
        </div>
      </Flex>
      <div style={{ marginTop: "5px" }}>
        {errTxt !== "" && (
          <span style={{ color: "red", paddingLeft: "10px" }}>
            【错误】{errTxt}, 请检查数据配置或联系管理员
          </span>
        )}
        {successTxt !== "" && (
          <span style={{ color: "green", paddingLeft: "10px" }}>
            【成功】{successTxt}
          </span>
        )}
      </div>
    </div>
  )
}

export default DataRecordToolbar
